package ph.gov.marikina.mcsmtms.domain;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.codehaus.jackson.annotate.JsonManagedReference;

import ph.gov.marikina.mcsmtms.constants.GlobalConstants;
import ph.gov.marikina.mcsmtms.constants.GlobalConstants.Direction;
import ph.gov.marikina.mcsmtms.constants.GlobalConstants.Roads;
import ph.gov.marikina.mcsmtms.utils.Utils;


// TODO: Auto-generated Javadoc
/**
 * The Class SituationReport.
 */
@Entity
@Table(name = "situation_report")
public class SituationReport implements Serializable {

	/** The count. */
	private Integer count;

	/** The id. */
	@Id
	@GeneratedValue
	@Column(name = "id")
	private Integer id;

	/** The description. */
	private String description;

	/** The last update. */
	private String lastUpdate;

	/** The last update date time. */
	@Column(name = "date_time", nullable = false)
	private Date lastUpdateDateTime;

	/** The situation. xxx */
	private String situation;

	/** The report source. */
	@Column(name = "source", nullable = false)
	private String reportSource;

	@Column(name = "reporter", nullable = false, insertable = false, updatable = false)
	private Integer reporter;
	
	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "reporter")
	private User user;

	/** The traffic condition. xxx */
	private String trafficCondition;

	/** The road. */
	@Column(name = "road", nullable = false)
	private String road;

	@Column(name = "direction", nullable = false)
	private String direction;

	@Column(name = "status", nullable = false)
	private String status;

	/* xxx */
	private boolean accessibleYn;

	@Column(name = "speed")
	private Double speed;

	/**
	 * Filter attributes startDate and EndDate
	 */
	private String startDate;

	private String endDate;

	@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER)
	@JoinColumn(name = "situation_report_id")
	private List<SituationSegment> situationSegmentList;
	
	private String remarks;

	/**
	 * Instantiates a new situation report.
	 */
	public SituationReport() {
	}

	/**
	 * Instantiates a new situation report.
	 * 
	 * @param situation
	 *            the situation
	 * @param road
	 *            the road
	 * @param reportSource
	 *            the report source
	 * @param updateTime
	 *            the update time
	 * @param trafficCondition
	 *            the traffic condition
	 * @param id
	 *            the id
	 * @param adjacentLandmark
	 *            the adjacent landmark
	 * @param description
	 *            the description
	 */
	public SituationReport(String situation, String road, String reportSource,
			Integer reporter, Date updateTime, String trafficCondition,
			Integer id, String direction, boolean accessibleYn,
			String description, Double speed) {
		this.situation = situation;
		this.road = road;
		this.reportSource = reportSource;
		this.lastUpdateDateTime = updateTime;
		this.trafficCondition = trafficCondition;
		this.id = id;
		this.description = description;
		this.reporter = reporter;
		this.direction = direction;
		this.accessibleYn = accessibleYn;
		this.speed = speed;
	}

	/**
	 * Instantiates a new situation report.
	 * 
	 * @param road
	 *            the road
	 * @param adjacentLandmark
	 *            the adjacent landmark
	 * @param description
	 *            the description
	 * @param situation
	 *            the situation
	 * @param reportSource
	 *            the report source
	 * @param trafficCondition
	 *            the traffic condition
	 * @param lastUpdate
	 *            the last update
	 */
	public SituationReport(String road, String adjacentLandmark,
			String description, String situation, String reportSource,
			String trafficCondition, String lastUpdate) {
		this.road = road;
		this.description = description;
		this.situation = situation;
		this.reportSource = reportSource;
		this.trafficCondition = trafficCondition;
		this.lastUpdate = lastUpdate;

	}

	/**
	 * Gets the count.
	 * 
	 * @return the count
	 */
	public Integer getCount() {
		return count;
	}

	/**
	 * Sets the count.
	 * 
	 * @param count
	 *            the new count
	 */
	public void setCount(Integer count) {
		this.count = count;
	}

	/**
	 * Gets the id.
	 * 
	 * @return the id
	 */
	public Integer getId() {
		return id;
	}

	/**
	 * Sets the id.
	 * 
	 * @param id
	 *            the new id
	 */
	public void setId(Integer id) {
		this.id = id;
	}

	/**
	 * NOT BEING PERSISTED Gets the description.
	 * 
	 * @return the description
	 */
	@Transient
	public String getDescription() {
		return description;
	}

	/**
	 * Sets the description.
	 * 
	 * @param description
	 *            the new description
	 */
	public void setDescription(String description) {
		this.description = description;
	}

	/**
	 * Gets the last update.
	 * 
	 * @return the last update
	 */
	public String getLastUpdate() {
		return lastUpdate;
	}

	/**
	 * Sets the last update.
	 * 
	 * @param lastUpdate
	 *            the new last update
	 */
	public void setLastUpdate(String lastUpdate) {
		this.lastUpdate = lastUpdate;
	}

	/**
	 * Gets the road.
	 * 
	 * @return the road
	 */
	public String getRoad() {
		return road;
	}

	public String getRoadDesc() {
		return Roads.getDescriptionByCode(road);
	}

	/**
	 * Sets the road.
	 * 
	 * @param road
	 *            the new road
	 */
	public void setRoad(String road) {
		this.road = road;
	}

	/**
	 * NOT BEING PERSISTED Gets the situation.
	 * 
	 * @return the situation
	 */
	@Transient
	public String getSituation() {
		return situation;
	}

	/**
	 * Sets the situation.
	 * 
	 * @param situation
	 *            the new situation
	 */
	public void setSituation(String situation) {
		this.situation = situation;
	}

	/**
	 * NOT BEING PERSISTED Gets the traffic condition.
	 * 
	 * @return the traffic condition
	 */
	@Transient
	public String getTrafficCondition() {
		return trafficCondition;
	}

	/**
	 * NOT BEING PERSISTED Sets the traffic condition.
	 * 
	 * @param trafficCondition
	 *            the new traffic condition
	 */
	@Transient
	public void setTrafficCondition(String trafficCondition) {
		this.trafficCondition = trafficCondition;
	}

	/**
	 * Gets the report source.
	 * 
	 * @return the report source
	 */
	public String getReportSource() {
		return reportSource;
	}

	/**
	 * Sets the report source.
	 * 
	 * @param reportSource
	 *            the new report source
	 */
	public void setReportSource(String reportSource) {
		this.reportSource = reportSource;
	}

	/**
	 * Gets the last update date time.
	 * 
	 * @return the last update date time
	 */
	public Date getLastUpdateDateTimeValue() {
		return lastUpdateDateTime;
	}

	public String getLastUpdateDateTimeString() {
		// return lastUpdateDateTime;
		return Utils.formatDefaultDate(lastUpdateDateTime);
	}

	/**
	 * Sets the last update date time.
	 * 
	 * @param lastUpdateDateTime
	 *            the new last update date time
	 */
	public void setLastUpdateDateTime(Date lastUpdateDateTime) {
		this.lastUpdateDateTime = lastUpdateDateTime;
	}

	public Integer getReporter() {
		return reporter;
	}

	public void setReporter(Integer reporter) {
		this.reporter = reporter;
	}

	public String getDirection() {
		return direction;
	}

	public String getDirectionDesc() {
		return Direction.getDescriptionByCode(direction);
	}

	public void setDirection(String direction) {
		this.direction = direction;
	}

	/**
	 * NOT BEING PERSISTED
	 * 
	 * @return
	 */
	@Transient
	public boolean getAccessibleYn() {
		return accessibleYn;
	}

	public void setAccessibleYn(boolean accessibleYn) {
		this.accessibleYn = accessibleYn;
	}

	public Double getSpeed() {
		return speed;
	}

	public void setSpeed(Double speed) {
		this.speed = speed;
	}

	// @OneToMany(cascade = CascadeType.ALL, fetch=FetchType.LAZY)
	// @OneToMany(cascade = CascadeType.ALL, fetch=FetchType.LAZY)
	// @JoinColumn(name = "situation_report_id", updatable = false, insertable =
	// false, nullable=false)
	// @JoinTable(
	// name = "situation_segment",
	// joinColumns = { @JoinColumn(name = "situation_report_id")}
	// )
	// @JoinColumn (name = "id")

	@JsonManagedReference
	public List<SituationSegment> getSituationSegmentList() {
		return situationSegmentList;
	}

	public void setSituationSegmentList(
			List<SituationSegment> situationSegmentList) {
		this.situationSegmentList = situationSegmentList;
	}

	public void addSituationSegment(SituationSegment situationSegment) {
		if (situationSegmentList == null) {
			situationSegmentList = new ArrayList<SituationSegment>();
		}

		situationSegment.setSituationReport(this);
		situationSegmentList.add(situationSegment);
	}

	/**
	 * Filter attributes public setter and getters
	 * 
	 * @return
	 */
	@Transient
	public String getStartDate() {
		return startDate;
	}

	public void setStartDate(String startDate) {
		this.startDate = startDate;
	}

	@Transient
	public String getEndDate() {
		return endDate;
	}

	public void setEndDate(String endDate) {
		this.endDate = endDate;
	}

	@Transient
	public String getSituationDescription() {
		// return situationDescription;
		if (situation != null && !"".equals(situation)) {
			return GlobalConstants.SituationTypes
					.getDescriptionByCode(situation);
		}
		return null;
	}

	@Transient
	public String getReportSourceDescription() {
		if (reportSource != null && !"".equals(reportSource)) {
			return GlobalConstants.UserTypes.getDescriptionByCode(reportSource);
		}
		return null;
	}

	@Transient
	public String getTrafficConditionDescription() {
		if (trafficCondition != null && !"".equals(trafficCondition)) {
			return GlobalConstants.TrafficConditionTypes
					.getDescriptionByCode(trafficCondition);
		}
		return null;
	}

	@Transient
	public String getRoadDescription() {
		if (road != null && !"".equals(road)) {
			return GlobalConstants.Roads.getDescriptionByCode(road);
		}
		return null;
	}

	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	public String getRemarks() {
		return remarks;
	}

	public void setRemarks(String remarks) {
		this.remarks = remarks;
	}
	
	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

}
